package com.yswy.app.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yswy.app.service.PayOrderService;
import com.yswy.app.service.WxPayKeyService;
import com.yswy.common.enums.PayMethodEnums;
import com.yswy.common.enums.WxPayMethodEnums;
import com.yswy.common.utils.DateUtils;
import com.yswy.common.utils.dingding.DingUtil;
import com.yswy.common.utils.redis.RedisConstants;
import com.yswy.common.utils.redis.RedisUtil;
import com.yswy.common.wxOrder.V3.WxPayConfigV3;
import com.yswy.common.zfbOrder.ZfbKeyVo;
import com.yswy.domain.entity.PayOrder;
import com.yswy.domain.entity.WxPayKey;
import com.yswy.domain.entity.ZfbPayKey;
import com.yswy.domain.mapper.WxPayKeyMapper;
import lombok.extern.slf4j.Slf4j;
import org.joda.time.LocalDateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.TimeUnit;

/**
 * @ClassName: WxPayServiceImpl
 * @Description: 微信支付接口
 * @Author: Matt
 * @Date: 2020/11/11 10:46
 **/
@Service
@Slf4j
public class WxPayKeyServiceImpl extends ServiceImpl<WxPayKeyMapper, WxPayKey>
        implements WxPayKeyService {

    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private DingUtil dingUtil;

    @Autowired
    private PayOrderService payOrderService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public WxPayConfigV3 cutAppId(String payMethod) {
        //查询当前已使用账号
        WxPayKey wxPayKey =  (WxPayKey) redisUtil.getObejct(payMethod);
        if (wxPayKey != null){
            boolean isCash = cashAppId(wxPayKey ,payMethod );
            if (isCash){
                wxPayKey = null ;
            }
        }
        if (wxPayKey == null){
            LambdaQueryWrapper<WxPayKey> lambdaQueryWrapper = new LambdaQueryWrapper<WxPayKey>();
            lambdaQueryWrapper.in(WxPayKey::getKeyStatus , 0 , 1).orderByAsc(WxPayKey::getLastUsdTime);
            if (payMethod.equals(WxPayMethodEnums.APP_PAY_USED.getMessage())){
                lambdaQueryWrapper.eq(WxPayKey::getOpenAppPay , true);
            }else if (payMethod.equals(WxPayMethodEnums.H5_PAY_USED.getMessage())){
                lambdaQueryWrapper.eq(WxPayKey::getOpenH5Pay , true);
            }else if (payMethod.equals(WxPayMethodEnums.Applet_PAY_USED.getMessage())){
                lambdaQueryWrapper.eq(WxPayKey::getOpenAppletPay , true);
            }else if (payMethod.equals(WxPayMethodEnums.Withdrawal_USED.getMessage())){
                lambdaQueryWrapper.eq(WxPayKey::getOpenWithdrawal , true);
            }else if (payMethod.equals(WxPayMethodEnums.Official_PAY_USED.getMessage())){
                lambdaQueryWrapper.eq(WxPayKey::getOpenOfficialPay , true);
            }
            List<WxPayKey> wxPayKeys  = list(lambdaQueryWrapper);
            if (wxPayKeys.size() <= 0 ){
                dingUtil.sendMsg(payMethod+"(紧急)支付宝预警公告：\n暂无可用支付宝账号，" +
                        "检测时间"+ DateUtils.getTime() +"，请管理员及时登陆处理。");
                throw new IllegalArgumentException("支付失败，请联系客服");

            }else {
                wxPayKey = wxPayKeys.get(0);
                wxPayKey.setKeyStatus(1);
                wxPayKey.setLastUsdTime(new Date());
                updateById(wxPayKey);
                dingUtil.sendMsg(payMethod + "支付宝切换公告：\n当前使用支付宝"+wxPayKey.getEMail());
                redisUtil.setForObjectTimeCustom(payMethod , wxPayKey,wxPayKey.getBigTime(), TimeUnit.MINUTES);
            }
        }
        WxPayConfigV3 wxPayConfigV3  = getWxPayConfigV3(null , wxPayKey);

        return wxPayConfigV3 ;
    }
    @Override
    public boolean cashAppId(WxPayKey wxPayKey ,String  payMethod) {
        //判断收款金额是否上限
        //查询其余平台收款金额
        if (redisUtil.hasKey(RedisConstants.WX_MONEY_APPID+wxPayKey.getMchId())){
            Integer payMoney = Integer.parseInt(redisUtil.get(RedisConstants.WX_MONEY_APPID+wxPayKey.getMchId()));
            if (payMoney >= wxPayKey.getMaxMoney() ){
                dingUtil.sendMsg("微信预警公告：\n微信账号"
                        +wxPayKey.getEMail()+"收款达到当日上限 +"+
                        "，检测时间"+
                        DateUtils.getTime() +"，请管理员及时登陆处理。");
                redisUtil.delete(payMethod);
                wxPayKey.setKeyStatus(3);
                updateById(wxPayKey);
                return true;
            }
        }

        return false ;
    }

    @Override
    public void recordPayMoney(Integer amount, String mchId) {
        Integer getAmount = amount /100 ;
        if (redisUtil.hasKey(RedisConstants.WX_MONEY_APPID+mchId)){
            Integer d = Integer.parseInt(
                    redisUtil.get(RedisConstants.WX_MONEY_APPID+mchId))
                    +getAmount ;
            redisUtil.set(RedisConstants.WX_MONEY_APPID+mchId
                    ,d.toString());
        }else {
            redisUtil.set(RedisConstants.WX_MONEY_APPID+mchId
                    ,getAmount.toString());
        }
    }

    @Override
    public WxPayConfigV3 getWxPayConfigV3(Long id  , WxPayKey wxPayKey) {
        if (wxPayKey == null){
            wxPayKey = getById(id);
        }
        WxPayConfigV3 wxPayConfig = new WxPayConfigV3();
        wxPayConfig.setId(wxPayKey.getId());
        wxPayConfig.setMchId(wxPayKey.getMchId());// 商户号
        wxPayConfig.setMchSerialNo(wxPayKey.getMchSerialNo());// 商户API证书序列号
        wxPayConfig.setPrivateKeyPath(wxPayKey.getApiclientKeyPem());// 商户私钥文件
        wxPayConfig.setCertificateKeyPath(wxPayKey.getCertificateKeyPath());
        wxPayConfig.setKey(wxPayKey.getKeyV3());// APIv3密钥
        wxPayConfig.setAppid(wxPayKey.getAppid());// APPID
        wxPayConfig.setDomain(wxPayKey.getDomain()); // 微信服务器地址
        wxPayConfig.setNotifyDomain(wxPayKey.getNotifyDomain());// 接收结果通知地址 支付
        wxPayConfig.setNotifyRefund(wxPayKey.getNotifyRefund());// 接收结果通知地址 退款
        return wxPayConfig;
    }
}
